/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(
    dead_code,
    mutable_transmutes,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut,
    unused_unsafe
)]
use crate::common::*;
extern "C" {
    fn free(_: *mut libc::c_void);
    fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
    fn sigemptyset(__set: *mut sigset_t) -> libc::c_int;
    fn sigaddset(__set: *mut sigset_t, __signo: libc::c_int) -> libc::c_int;
    fn sigismember(__set: *const sigset_t, __signo: libc::c_int) -> libc::c_int;
    fn sigprocmask(
        __how: libc::c_int,
        __set: *const sigset_t,
        __oset: *mut sigset_t,
    ) -> libc::c_int;
    fn sigaction(
        __sig: libc::c_int,
        __act: *const sigaction,
        __oact: *mut sigaction,
    ) -> libc::c_int;
    fn sigpending(__set: *mut sigset_t) -> libc::c_int;
    static mut sudo_defs_table: [sudo_defs_types; 0];
    static mut NewArgc: libc::c_int;
    static mut NewArgv: *mut *mut libc::c_char;
    fn audit_failure(
        argc: libc::c_int,
        argv: *mut *mut libc::c_char,
        fmt: *const libc::c_char,
        _: ...
    ) -> libc::c_int;
    fn log_auth_failure(status: libc::c_int, tries: libc::c_uint) -> bool;
    fn log_warningx(flags: libc::c_int, fmt: *const libc::c_char, _: ...) -> bool;
    fn sudo_memset_s(v: *mut libc::c_void, smax: size_t, c: libc::c_int, n: size_t) -> libc::c_int;
    fn dcgettext(
        __domainname: *const libc::c_char,
        __msgid: *const libc::c_char,
        __category: libc::c_int,
    ) -> *mut libc::c_char;
    static mut sudo_printf:
        Option<unsafe extern "C" fn(libc::c_int, *const libc::c_char, ...) -> libc::c_int>;
    fn sudo_debug_enter_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
    );
    fn sudo_debug_exit_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
    );
    fn sudo_debug_exit_bool_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
        ret: bool,
    );
    fn sudo_debug_exit_int_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
        ret: libc::c_int,
    );
    fn sudo_debug_exit_str_masked_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        subsys: libc::c_int,
        ret: *const libc::c_char,
    );
    static mut sudoers_subsystem_ids: [libc::c_uint; 0];
    static mut sudo_conv: sudo_conv_t;
    fn sudo_pam_init(pw: *mut passwd, auth: *mut sudo_auth) -> libc::c_int;
    fn sudo_pam_verify(
        pw: *mut passwd,
        prompt: *mut libc::c_char,
        auth: *mut sudo_auth,
        callback: *mut sudo_conv_callback,
    ) -> libc::c_int;
    fn sudo_pam_approval(pw: *mut passwd, auth: *mut sudo_auth, exempt: bool) -> libc::c_int;
    fn sudo_pam_cleanup(pw: *mut passwd, auth: *mut sudo_auth) -> libc::c_int;
    fn sudo_pam_begin_session(
        pw: *mut passwd,
        user_env: *mut *mut *mut libc::c_char,
        auth: *mut sudo_auth,
    ) -> libc::c_int;
    fn sudo_pam_end_session(pw: *mut passwd, auth: *mut sudo_auth) -> libc::c_int;
}

pub const FLAG_DISABLED: libc::c_int = 0x02;
pub const FLAG_STANDALONE: libc::c_int = 0x04;
pub const FLAG_ONEANDONLY: libc::c_int = 0x08;
pub const AUTH_SUCCESS: libc::c_int = 0;
pub const AUTH_FAILURE: libc::c_int = 1;
pub const AUTH_INTR: libc::c_int = 2;
pub const AUTH_FATAL: libc::c_int = 3;

#[macro_export]
macro_rules! IS_DISABLED {
    ($x:expr) => {
        ((*($x)).flags & FLAG_DISABLED)
    };
}

#[macro_export]
macro_rules! IS_STANDALONE {
    ($x:expr) => {
        ((*($x)).flags & FLAG_STANDALONE)
    };
}

#[macro_export]
macro_rules! IS_ONEANDONLY {
    ($x:expr) => {
        ((*($x)).flags & FLAG_ONEANDONLY)
    };
}

pub type __sighandler_t = Option<unsafe extern "C" fn(libc::c_int) -> ()>;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct sigaction {
    pub __sigaction_handler: C2RustUnnamed_9,
    pub sa_mask: __sigset_t,
    pub sa_flags: libc::c_int,
    pub sa_restorer: Option<unsafe extern "C" fn() -> ()>,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union C2RustUnnamed_9 {
    pub sa_handler: __sighandler_t,
    pub sa_sigaction:
        Option<unsafe extern "C" fn(libc::c_int, *mut siginfo_t, *mut libc::c_void) -> ()>,
}
pub type sudo_conv_t = Option<
    unsafe extern "C" fn(
        libc::c_int,
        *const sudo_conv_message,
        *mut sudo_conv_reply,
        *mut sudo_conv_callback,
    ) -> libc::c_int,
>;
pub type sudo_printf_t =
    Option<unsafe extern "C" fn(libc::c_int, *const libc::c_char, ...) -> libc::c_int>;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct sudo_auth {
    pub flags: libc::c_int,
    pub status: libc::c_int,
    pub name: *mut libc::c_char,
    pub data: *mut libc::c_void,
    pub init: Option<unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int>,
    pub setup: Option<
        unsafe extern "C" fn(*mut passwd, *mut *mut libc::c_char, *mut sudo_auth) -> libc::c_int,
    >,
    pub verify: Option<
        unsafe extern "C" fn(
            *mut passwd,
            *mut libc::c_char,
            *mut sudo_auth,
            *mut sudo_conv_callback,
        ) -> libc::c_int,
    >,
    pub approval: Option<unsafe extern "C" fn(*mut passwd, *mut sudo_auth, bool) -> libc::c_int>,
    pub cleanup: Option<unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int>,
    pub begin_session: Option<
        unsafe extern "C" fn(
            *mut passwd,
            *mut *mut *mut libc::c_char,
            *mut sudo_auth,
        ) -> libc::c_int,
    >,
    pub end_session: Option<unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int>,
}
static mut auth_switch: [sudo_auth; 2] = unsafe {
    [
        {
            sudo_auth {
                flags: 0x4 as libc::c_int,
                status: 1 as libc::c_int,
                name: b"pam\0" as *const u8 as *const libc::c_char as *mut libc::c_char,
                data: 0 as *const libc::c_void as *mut libc::c_void,
                init: Some(
                    sudo_pam_init
                        as unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int,
                ),
                setup: None,
                verify: Some(
                    sudo_pam_verify
                        as unsafe extern "C" fn(
                            *mut passwd,
                            *mut libc::c_char,
                            *mut sudo_auth,
                            *mut sudo_conv_callback,
                        ) -> libc::c_int,
                ),
                approval: Some(
                    sudo_pam_approval
                        as unsafe extern "C" fn(*mut passwd, *mut sudo_auth, bool) -> libc::c_int,
                ),
                cleanup: Some(
                    sudo_pam_cleanup
                        as unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int,
                ),
                begin_session: Some(
                    sudo_pam_begin_session
                        as unsafe extern "C" fn(
                            *mut passwd,
                            *mut *mut *mut libc::c_char,
                            *mut sudo_auth,
                        ) -> libc::c_int,
                ),
                end_session: Some(
                    sudo_pam_end_session
                        as unsafe extern "C" fn(*mut passwd, *mut sudo_auth) -> libc::c_int,
                ),
            }
            //init
        },
        {
            sudo_auth {
                flags: 0 as libc::c_int,
                status: 1 as libc::c_int,
                name: 0 as *const libc::c_char as *mut libc::c_char,
                data: 0 as *const libc::c_void as *mut libc::c_void,
                init: None,
                setup: None,
                verify: None,
                approval: None,
                cleanup: None,
                begin_session: None,
                end_session: None,
            }
            //init
        },
    ]
};
static mut standalone: bool = false;

/*
 * Initialize sudoers authentication method(s).
 * Returns 0 on success and -1 on error.
 */
#[no_mangle]
pub fn sudo_auth_init(mut pw: *mut passwd) -> libc::c_int {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    let mut status: libc::c_int = AUTH_SUCCESS;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    unsafe {
        if (auth_switch[0 as libc::c_int as usize].name).is_null() {
            debug_return_int!(0);
        }

        /* Initialize auth methods and unconfigure the method if necessary. */
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).init).is_some() && IS_DISABLED!(auth) == 0 {
                /* Disable if it failed to init unless there was a fatal error. */
                status = ((*auth).init).expect("non-null function pointer")(pw, auth);
                if status == AUTH_FAILURE {
                    // (*auth).flags |= FLAG_DISABLED;
                    SET!((*auth).flags, FLAG_DISABLED);
                } else if status == AUTH_FATAL {
                    break; /* assume error msg already printed */
                }
            }
            auth = auth.offset(1);
        }

        /*
         * Make sure we haven't mixed standalone and shared auth methods.
         * If there are multiple standalone methods, only use the first one.
         */
        standalone = IS_STANDALONE!(&mut auth_switch[0 as libc::c_int as usize]) != 0;

        if standalone {
            let mut found: bool = false;
            auth = auth_switch.as_mut_ptr();
            while !((*auth).name).is_null() {
                if IS_DISABLED!(auth) != 0 {
                    auth = auth.offset(1);
                    continue;
                }
                if IS_STANDALONE!(auth) == 0 {
                    audit_failure(
                        NewArgc,
                        NewArgv,
                        b"invalid authentication methods\0" as *const u8 as *const libc::c_char,
                    );
                    log_warningx(
                        SLOG_SEND_MAIL,
                        b"Invalid authentication methods compiled into sudo!  You may not mix standalone and non-standalone authentication.\0"
                            as *const u8 as *const libc::c_char,
                    );
                    debug_return_int!(-1);
                }
                if !found {
                    /* Found first standalone method. */
                    found = true;
                    auth = auth.offset(1);
                    continue;
                }
                /* Disable other standalone methods. */
                SET!((*auth).flags, FLAG_DISABLED);

                auth = auth.offset(1);
            }
        }

        /* Set FLAG_ONEANDONLY if there is only one auth method. */
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            /* Find first enabled auth method. */
            if IS_DISABLED!(auth) == 0 {
                let mut first: *mut sudo_auth = auth;

                /* Check for others. */
                while !((*auth).name).is_null() {
                    if IS_DISABLED!(auth) == 0 {
                        break;
                    }
                    auth = auth.offset(1);
                }

                if ((*auth).name).is_null() {
                    SET!((*first).flags, FLAG_ONEANDONLY);
                }

                break;
            }
            auth = auth.offset(1);
        }
    } //unsafe

    unsafe {
        debug_return_int!(if status == AUTH_FATAL {
            -(1 as libc::c_int)
        } else {
            0 as libc::c_int
        });
    }
}

/*
 * Cleanup all authentication approval methods.
 * Returns true on success, false on failure and -1 on error.
 */
#[no_mangle]
pub fn sudo_auth_approval(
    mut pw: *mut passwd,
    mut validated: libc::c_int,
    mut exempt: bool,
) -> libc::c_int {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    /* Call approval routines. */
    unsafe {
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).approval).is_some() && IS_DISABLED!(auth) == 0 {
                let mut status: libc::c_int =
                    ((*auth).approval).expect("non-null function pointer")(pw, auth, exempt);

                if status != AUTH_SUCCESS {
                    /* Assume error msg already printed. */
                    log_auth_failure(validated, 0 as libc::c_int as libc::c_uint);
                    debug_return_int!(if status == AUTH_FAILURE {
                        false as libc::c_int
                    } else {
                        -(1 as libc::c_int)
                    })
                }
            }
            auth = auth.offset(1);
        }
    } //unsafe

    unsafe {
        debug_return_int!(true as libc::c_int);
    }
}

/*
 * Cleanup all authentication methods.
 * Returns 0 on success and -1 on error.
 */
#[no_mangle]
pub fn sudo_auth_cleanup(mut pw: *mut passwd) -> libc::c_int {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    /* Call cleanup routines. */
    unsafe {
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).cleanup).is_some() && IS_DISABLED!(auth) == 0 {
                let mut status: libc::c_int =
                    ((*auth).cleanup).expect("non-null function pointer")(pw, auth);
                if status == AUTH_FATAL {
                    /* Assume error msg already printed. */
                    debug_return_int!(-1);
                }
            }
            auth = auth.offset(1);
        }
    } //unsafe
    unsafe {
        debug_return_int!(0);
    }
}
fn pass_warn() {
    unsafe {
        let mut warning: *const libc::c_char = def_badpass_message!();
        debug_decl!(SUDOERS_DEBUG_AUTH!());

        sudo_printf.expect("non-null function pointer")(
            SUDO_CONV_ERROR_MSG | SUDO_CONV_PREFER_TTY,
            b"%s\n\0" as *const u8 as *const libc::c_char,
            warning,
        );
    } //unsafe
    unsafe {
        debug_return!();
    }
}
fn user_interrupted() -> bool {
    let mut mask: sigset_t = sigset_t { __val: [0; 16] };

    unsafe {
        sigpending(&mut mask) == 0 as libc::c_int
            && (sigismember(&mask, SIGINT) != 0 || sigismember(&mask, SIGQUIT) != 0)
    } //unsafe
}

/*
 * Verify the specified user.
 * Returns true if verified, false if not or -1 on error.
 */
#[no_mangle]
pub fn verify_user(
    mut pw: *mut passwd,
    mut prompt: *mut libc::c_char,
    mut validated: libc::c_int,
    mut callback: *mut sudo_conv_callback,
) -> libc::c_int {
    let mut ntries: libc::c_uint = 0;
    let mut ret: libc::c_int = 0;
    let mut status: libc::c_int = 0;
    let mut success: libc::c_int = 1 as libc::c_int;
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    let mut mask: sigset_t = sigset_t { __val: [0; 16] };
    let mut omask: sigset_t = sigset_t { __val: [0; 16] };
    let mut sa: sigaction = sigaction {
        __sigaction_handler: C2RustUnnamed_9 { sa_handler: None },
        sa_mask: sigset_t { __val: [0; 16] },
        sa_flags: 0,
        sa_restorer: None,
    };
    let mut saved_sigtstp: sigaction = sigaction {
        __sigaction_handler: C2RustUnnamed_9 { sa_handler: None },
        sa_mask: sigset_t { __val: [0; 16] },
        sa_flags: 0,
        sa_restorer: None,
    };
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    /* Make sure we have at least one auth method. */
    unsafe {
        if (auth_switch[0 as libc::c_int as usize].name).is_null() {
            audit_failure(
                NewArgc,
                NewArgv,
                b"no authentication methods\0" as *const u8 as *const libc::c_char,
            );
            log_warningx(
            SLOG_SEND_MAIL,
            b"There are no authentication methods compiled into sudo!  If you want to turn off authentication, use the --disable-authentication configure option.\0"
                as *const u8 as *const libc::c_char,
        );

            debug_return_int!(-1);
        }

        /* Enable suspend during password entry. */
        sigemptyset(&mut sa.sa_mask);
        sa.sa_flags = SA_RESTART;
        sa.__sigaction_handler.sa_handler = None;
        sigaction(SIGTSTP, &sa, &mut saved_sigtstp);

        /*
         * We treat authentication as a critical section and block
         * keyboard-generated signals such as SIGINT and SIGQUIT
         * which might otherwise interrupt a sleep(3).
         * They are temporarily unblocked by auth_getpass().
         */
        sigemptyset(&mut mask);
        sigaddset(&mut mask, SIGINT);
        sigaddset(&mut mask, SIGQUIT);
        sigprocmask(0 as libc::c_int, &mask, &mut omask);

        ntries = 0 as libc::c_uint;
        'done: while ntries < def_passwd_tries!() {
            let mut num_methods: libc::c_int = 0 as libc::c_int;
            let mut pass: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();

            /* If user attempted to interrupt password verify, quit now. */
            if user_interrupted() {
                break 'done;
            }
            if ntries != 0 as libc::c_int as libc::c_uint {
                pass_warn();
            }

            /* Do any per-method setup and unconfigure the method if needed */
            auth = auth_switch.as_mut_ptr();
            while !((*auth).name).is_null() {
                if IS_DISABLED!(auth) == 0 {
                    num_methods += 1;
                    if ((*auth).setup).is_some() {
                        status = ((*auth).setup).expect("non-null function pointer")(
                            pw,
                            &mut prompt,
                            auth,
                        );
                        if status == AUTH_FAILURE {
                            (*auth).flags |= FLAG_DISABLED;
                        } else if status == AUTH_FATAL || user_interrupted() as libc::c_int != 0 {
                            break 'done; /* assume error msg already printed */
                        }
                    }
                }
                auth = auth.offset(1);
            }
            if num_methods == 0 as libc::c_int {
                audit_failure(
                    NewArgc,
                    NewArgv,
                    b"no authentication methods\0" as *const u8 as *const libc::c_char,
                );
                log_warningx(
                    SLOG_SEND_MAIL,
                    b"Unable to initialize authentication methods.\0" as *const u8
                        as *const libc::c_char,
                );
                debug_return_int!(-1)
            }

            /* Get the password unless the auth function will do it for us */
            if !standalone {
                pass = auth_getpass(prompt, 0x1 as libc::c_int, callback);
                if pass.is_null() {
                    break;
                }
            }

            /* Call authentication functions. */
            auth = auth_switch.as_mut_ptr();
            while !((*auth).name).is_null() {
                if IS_DISABLED!(auth) == 0 {
                    (*auth).status = ((*auth).verify).expect("non-null function pointer")(
                        pw,
                        if standalone as libc::c_int != 0 {
                            prompt
                        } else {
                            pass
                        },
                        auth,
                        callback,
                    );
                    success = (*auth).status;
                    if success != AUTH_FAILURE {
                        break;
                    }
                }
                auth = auth.offset(1);
            }

            if !pass.is_null() {
                sudo_memset_s(
                    pass as *mut libc::c_void,
                    SUDO_CONV_REPL_MAX as size_t,
                    0 as libc::c_int,
                    strlen(pass),
                );
                free(pass as *mut libc::c_void);
            }
            if success != AUTH_FAILURE {
                break;
            }
            ntries = ntries.wrapping_add(1);
        }

        // done:
        /* Restore signal handlers and signal mask. */
        sigaction(SIGTSTP, &saved_sigtstp, std::ptr::null_mut::<sigaction>());
        sigprocmask(SIG_SETMASK, &omask, std::ptr::null_mut::<sigset_t>());
        match success {
            AUTH_SUCCESS => {
                ret = true as libc::c_int;
            }
            AUTH_INTR | AUTH_FAILURE => {
                if ntries != 0 as libc::c_uint {
                    validated |= FLAG_BAD_PASSWORD;
                }
                log_auth_failure(validated, ntries);
                ret = false as libc::c_int;
            }
            _ => {
                log_auth_failure(validated, 0 as libc::c_int as libc::c_uint);
                ret = -(1 as libc::c_int);
            }
        }
    } //unsafe

    unsafe {
        debug_return_int!(ret);
    }
}

/*
 * Call authentication method begin session hooks.
 * Returns 1 on success and -1 on error.
 */
#[no_mangle]
pub fn sudo_auth_begin_session(
    mut pw: *mut passwd,
    mut user_env: *mut *mut *mut libc::c_char,
) -> libc::c_int {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }
    unsafe {
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).begin_session).is_some() && IS_DISABLED!(auth) == 0 {
                let mut status: libc::c_int =
                    ((*auth).begin_session).expect("non-null function pointer")(pw, user_env, auth);
                if status != AUTH_SUCCESS {
                    /* Assume error msg already printed. */
                    debug_return_int!(-1);
                }
            }
            auth = auth.offset(1);
        }
    } //unsafe
    unsafe {
        debug_return_int!(1);
    }
}

#[no_mangle]
pub fn sudo_auth_needs_end_session() -> bool {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    let mut needed: bool = false;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    unsafe {
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).end_session).is_some() && IS_DISABLED!(auth) == 0 {
                needed = true;
                break;
            }
            auth = auth.offset(1);
        }
    } //unsafe
    unsafe {
        debug_return_bool!(needed);
    }
}

/*
 * Call authentication method end session hooks.
 * Returns 1 on success and -1 on error.
 */
#[no_mangle]
pub fn sudo_auth_end_session(mut pw: *mut passwd) -> libc::c_int {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    let mut status: libc::c_int = 0;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    unsafe {
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            if ((*auth).end_session).is_some() && IS_DISABLED!(auth) == 0 {
                status = ((*auth).end_session).expect("non-null function pointer")(pw, auth);
                if status == AUTH_FATAL {
                    /* Assume error msg already printed. */
                    debug_return_int!(-1);
                }
            }
            auth = auth.offset(1);
        }
    } //unsafe

    unsafe {
        debug_return_int!(1);
    }
}

/*
 * Prompts the user for a password using the conversation function.
 * Returns the plaintext password or NULL.
 * The user is responsible for freeing the returned value.
 */
#[no_mangle]
pub fn auth_getpass(
    mut prompt: *const libc::c_char,
    mut type_0: libc::c_int,
    mut callback: *mut sudo_conv_callback,
) -> *mut libc::c_char {
    let mut msg: sudo_conv_message = sudo_conv_message {
        msg_type: 0,
        timeout: 0,
        msg: std::ptr::null::<libc::c_char>(),
    };
    let mut repl: sudo_conv_reply = sudo_conv_reply {
        reply: std::ptr::null_mut::<libc::c_char>(),
    };
    let mut mask: sigset_t = sigset_t { __val: [0; 16] };
    let mut omask: sigset_t = sigset_t { __val: [0; 16] };
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    /* Mask user input if pwfeedback set and echo is off. */
    unsafe {
        if type_0 == SUDO_CONV_PROMPT_ECHO_OFF as libc::c_int && def_pwfeedback!() != 0 {
            type_0 = SUDO_CONV_PROMPT_MASK;
        }

        /* If visiblepw set, do not error out if there is no tty. */
        if def_visiblepw!() != 0 {
            type_0 |= SUDO_CONV_PROMPT_ECHO_OK;
        }

        /* Unblock SIGINT and SIGQUIT during password entry. */
        /* XXX - do in tgetpass() itself instead? */
        sigemptyset(&mut mask);
        sigaddset(&mut mask, SIGINT);
        sigaddset(&mut mask, SIGQUIT);
        sigprocmask(SIG_UNBLOCK, &mask, &mut omask);

        /* Call conversation function. */
        memset(
            &mut msg as *mut sudo_conv_message as *mut libc::c_void,
            0 as libc::c_int,
            ::core::mem::size_of::<sudo_conv_message>() as libc::c_ulong,
        );
        msg.msg_type = type_0;
        msg.timeout = def_passwd_timeout!().tv_sec as libc::c_int;
        msg.msg = prompt;
        memset(
            &mut repl as *mut sudo_conv_reply as *mut libc::c_void,
            0 as libc::c_int,
            ::core::mem::size_of::<sudo_conv_reply>() as libc::c_ulong,
        );
        sudo_conv.expect("non-null function pointer")(
            1 as libc::c_int,
            &mut msg as *mut sudo_conv_message as *const sudo_conv_message,
            &mut repl,
            callback,
        );
        /* XXX - check for ENOTTY? */

        /* Restore previous signal mask. */
        sigprocmask(2 as libc::c_int, &omask, std::ptr::null_mut::<sigset_t>());

        debug_return_str_masked!(repl.reply);
    } //unsafe
}
#[no_mangle]
pub fn dump_auth_methods() {
    let mut auth: *mut sudo_auth = std::ptr::null_mut::<sudo_auth>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_AUTH!());
    }

    unsafe {
        sudo_printf.expect("non-null function pointer")(
            SUDO_CONV_INFO_MSG,
            b"Authentication methods:\0" as *const u8 as *const libc::c_char,
        );
        auth = auth_switch.as_mut_ptr();
        while !((*auth).name).is_null() {
            sudo_printf.expect("non-null function pointer")(
                SUDO_CONV_INFO_MSG,
                b" '%s'\0" as *const u8 as *const libc::c_char,
                (*auth).name,
            );
            auth = auth.offset(1);
        }
        sudo_printf.expect("non-null function pointer")(
            SUDO_CONV_INFO_MSG,
            b"\n\0" as *const u8 as *const libc::c_char,
        );

        debug_return!();
    } //unsafe
}
